定义
在java中 null既不是对象,也不是一种类型,而是一种特殊的值。在这里我要说的是一种特殊情况哈。
编译器自带的优化
总所周知,我们的java代码中String对象那如果直接用+连连接字符串可能导致效率变低。但是现在在java1.5以后编译器对其自动做了优化,如果你有时间打开反编译的源码看看,你会发现,String a=”b”+”cc”;这个代码在编译器中优化了,优化方式为在这行代码的开始的地方声明一个StringBuilder,然后不断append后面的字符串。因此对于java来说你用StringBuilder和String的+其实效率都是一样的,但是为了保证一个良好的习惯还是用StringBuilder好一点。
+导致的问题
我们用””+null,这个空对象,会生成一个null字符串。这是为什么呢?
前文已经提到,我们已经用编译器做了优化,String对象的+被优化为了StringBuilder的append,然而我们看看append的源码,你就会发现为何是null字符串了。
public StringBuilder append(Object obj) { return append(String.valueOf(obj)); } @Override public StringBuilder append(String str) { super.append(str); return this; }查看源码发现,append方法向上调用了其抽象类AbstractStringBuilder方法的append方法,在看
public AbstractStringBuilder append(String str) { if (str == null) return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars(0, len, value, count); count += len; return this; } private AbstractStringBuilder appendNull() { int c = count; ensureCapacityInternal(c + 4); final char[] value = this.value; value[c++] = 'n'; value[c++] = 'u'; value[c++] = 'l'; value[c++] = 'l'; count = c; return this; }你看真相大白了,在这个抽象类的这个append方法中,先进行了判断,如果为null,则是把这个null作为一个字符串加上去。因此解决了上面我们遇到的问题,为何String对象+null,会条件一个null字符串。 测试案例如下:
public static void main(String[] args) { String a="dh"; String b=a+null; System.out.println(b); }结果如下:
dhnull